package com.blueocean_health.care.management;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.servlet.MultipartConfigElement;
import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.blueocean_health.care.management.interceptor.AppValidateInterceptor;
import com.blueocean_health.care.management.interceptor.LogFilter;
import com.blueocean_health.care.management.interceptor.ValidateInterceptor;
import com.blueocean_health.care.management.interceptor.WebRequestAroundAdvice;

@SpringBootApplication // 申明让spring boot自动给程序进行必要的配置
@ServletComponentScan // 开启后支持自定义Servlet和Filter
@EnableScheduling // 支持定时任务
@MapperScan(basePackages = { "com.blueocean_health.care.management.mapper" }
// ,sqlSessionFactoryRef = ""
)
@EnableTransactionManagement(proxyTargetClass = true) // 启注解事务管理
/**
 * 此项目的核心初始化类
 */
public class AppStart extends WebMvcConfigurerAdapter {
	@Bean
	public WebRequestAroundAdvice webRequestAroundAdvice() {
		return new WebRequestAroundAdvice();
	}

	public static void main(String[] args) {
		String property = System.getProperty("user.dir");
		String parentpath = new File(property).getParent();

		// File coreFile = new File("D:/core.properties");
		System.out.println(parentpath);
		InputStream in = null;
		Properties prop = new Properties();
		try {
			FileInputStream coreFile = new FileInputStream(parentpath + "/core_properties/core.properties");
			// in = new FileInputStream(coreFile);
			in = new BufferedInputStream(coreFile);
			// prop.load(in);//直接这么写，如果properties文件中有汉子，则汉字会乱码。因为未设置编码格式。
			prop.load(new InputStreamReader(in, "utf-8"));
			// prop.load(in);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
			}
		}
		SpringApplication app = new SpringApplication(AppStart.class);
		app.setDefaultProperties(prop);
		System.setProperty("LOG_LEVEL", prop.getProperty("LOG_LEVEL"));
		System.setProperty("LOG_FILE", prop.getProperty("LOG_FILE"));
		app.run(args);
		// SpringApplication.run(AppStart.class, args);
		init(false);
	}

	/**
	 * 判断是否为服务器环境
	 * 
	 * @param isServer
	 *            true:服务器环境 false:本地环境
	 */
	public static void init(boolean isServer) {

	}

	@Autowired
	private ValidateInterceptor validateInterceptor;
	@Autowired
	private AppValidateInterceptor appValidateInterceptor;

	/**
	 * 注册一下自己的拦截器
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(validateInterceptor).addPathPatterns("/web/**").excludePathPatterns("/web/user/login")
				.excludePathPatterns("/error").excludePathPatterns("/test/**")
				.excludePathPatterns("/web/order/blueoceanselectzhdzexcelall");
		registry.addInterceptor(appValidateInterceptor).addPathPatterns("/app/**").excludePathPatterns("/error")
				.excludePathPatterns("/app/user-patient/phonecode").excludePathPatterns("/app/user-patient/login")
				.excludePathPatterns("/test/**").excludePathPatterns("/app/static/**");
		super.addInterceptors(registry);
	}

	@Value("${picture.filePath}")
	private String filePath;

	/**
	 * 添加静态资源映射
	 */
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/**").addResourceLocations("classpath:/static/", "file:" + filePath);
	}

	/**
	 * 替换json框架为fastjson
	 * 
	 * @return
	 */
	@Bean
	public HttpMessageConverters fastJsonHttpMessageConverters() {
		FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
		FastJsonConfig fastJsonConfig = new FastJsonConfig();
		fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
				SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteNullStringAsEmpty);
		fastConverter.setFastJsonConfig(fastJsonConfig);

		HttpMessageConverter<?> converter = fastConverter;
		// 处理中文乱码问题
		List<MediaType> fastMediaTypes = new ArrayList<>();
		fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
		fastConverter.setSupportedMediaTypes(fastMediaTypes);

		return new HttpMessageConverters(converter);
	}

	/**
	 * 限制上传文件大小
	 * 
	 * @return
	 */
	@Bean
	public MultipartConfigElement multipartConfigElement() {
		MultipartConfigFactory factory = new MultipartConfigFactory();
		// 设置单个文件大小
		factory.setMaxFileSize("102400KB");
		// 设置总上传数据总大小
		factory.setMaxRequestSize("102400KB");
		return factory.createMultipartConfig();
	}

	/**
	 * 跨域问题处理
	 * 
	 * @return
	 */
	@Bean
	public CorsFilter corsFilter() {
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		CorsConfiguration corsConfiguration = new CorsConfiguration();
		corsConfiguration.addAllowedOrigin("*");
		corsConfiguration.addAllowedHeader("*");
		corsConfiguration.addAllowedMethod("*");
		source.registerCorsConfiguration("/**", corsConfiguration);
		return new CorsFilter(source);
	}

	/**
	 * 注入数据连接池
	 */
	/*
	 * @Bean public DataSource registerDataSource(){ DataSource ds = null;
	 * Properties prop = new Properties(); try (InputStream in =
	 * AppStart.class.getClassLoader().getResourceAsStream("druid.properties")){
	 * prop.load(in); ds = DruidDataSourceFactory.createDataSource(prop); }
	 * catch (Exception e) { e.printStackTrace(); } return ds; }
	 */

	@Bean
	public SqlSessionFactory registerSqlSessionFactoryBean(DataSource dataSource) throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		// 设置Mapper文件的路径
		bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
		// 设置mybatis的配置文件
		bean.setConfigLocation(resolver.getResource("classpath:mybatis.xml"));
		// 设置别名包
		bean.setTypeAliasesPackage("com.blueocean_health.care.management.domain");
		bean.setVfs(SpringBootVFS.class);
		return bean.getObject();
	}
	@Bean
	public FilterRegistrationBean testFilterRegistration() {

	   FilterRegistrationBean registration = new FilterRegistrationBean();
	   registration.setFilter(new LogFilter());
	   registration.addUrlPatterns("/*");
	   registration.setName("logFilter");
	   registration.setOrder(1);
	   return registration;
	}
	@Bean
	public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {

		return new SqlSessionTemplate(sqlSessionFactory);
	}

}
